package com.tony.business.config;

import com.alibaba.fastjson.JSONObject;
import com.tony.business.service.LogService;
import com.tony.mapper.domain.po.Log;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Arrays;


/**
 * @author x
 * @date 2020-01-01
 */
@Component
@Aspect
@Order(30)
@Slf4j
public class LogAspect {

    private HttpServletRequest request;

    private LogService logService;

    @Autowired
    public LogAspect(HttpServletRequest request, LogService logService) {
        this.request = request;
        this.logService = logService;
    }

    @Pointcut("execution(* com.tony.business.controller..*(..))")
    private void logPointCut(){}

    @Before("logPointCut()")
    private void before(JoinPoint joinPoint){
        log.info("获取request的各个参数");
        log.info("Protocol={}",request.getProtocol());
        log.info("ContentType={}",request.getContentType());
        log.info("CharacterEncoding={}",request.getCharacterEncoding());
        log.info("RequestedSessionId={}",request.getRequestedSessionId());
        log.info("Scheme={}",request.getScheme());
        log.info("method={}",request.getMethod());
        log.info("ip={}",request.getRemoteAddr());
        log.info("url={}",request.getRequestURL());
        log.info("QueryString={}",request.getQueryString());
        log.info("methodName={}",joinPoint.getSignature().getDeclaringTypeName()+","+joinPoint.getSignature().getName());
        log.info("joinPointArgs={}", Arrays.toString(joinPoint.getArgs()));
        log.info("requestArgs={}", JSONObject.toJSONString(request.getParameterMap()));
        Log log = new Log();
        log.setProtocol(request.getProtocol());
        log.setContentType(request.getContentType());
        log.setCharacterEncoding(request.getCharacterEncoding());
        log.setRequestedSessionId(request.getRequestedSessionId());
        log.setScheme(request.getScheme());
        log.setMethod(request.getMethod());
        log.setIp(request.getRemoteAddr());
        log.setUrl(request.getRequestURL().toString());
        log.setQueryString(request.getQueryString());
        log.setMethodName(joinPoint.getSignature().getDeclaringTypeName()+","+joinPoint.getSignature().getName());
        log.setJoinPointArgs(Arrays.toString(joinPoint.getArgs()));
        log.setRequestArgs(JSONObject.toJSONString(request.getParameterMap()));
        log.setToken(request.getHeader("token"));
        Object object = request.getAttribute("userInfo");
        if(object!=null) {
            log.setUserInfo(JSONObject.toJSONString(object));
        }
        logService.save(log);
        request.setAttribute("logId",log.getId());
    }

    @After(value = "logPointCut()")
    private void after(){
        log.info("方法返回");
    }

    @AfterReturning(returning = "obj",pointcut = "logPointCut()")
    private void afterReturning(Object obj){
        log.info("returning={}", obj);
        if (obj != null) {
            Log log = new Log();
            log.setId((Long) request.getAttribute("logId"));
            log.setResult(obj.toString());
            logService.updateById(log);
        }
    }

    @AfterThrowing(pointcut = "logPointCut()",throwing = "e")
    private void afterThrowing(Throwable e){
        StringWriter stringWriter=new StringWriter();
        e.printStackTrace(new PrintWriter(stringWriter,true));
        log.error(stringWriter.getBuffer().toString());
        Log log = new Log();
        log.setId((Long) request.getAttribute("logId"));
        log.setError(stringWriter.getBuffer().toString());
        logService.updateById(log);
    }
}
